package model.member;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import model.member.exception.InvalidNotFoundException;
import model.member.paging.Admin_ListVO;
import model.member.paging.CommonConstants;
import model.member.paging.ListVO;
import model.member.paging.PagingBean;

public class MemberService {
	private MemberDao memberDao;

	public MemberService(MemberDao memberDao) {
		super();
		this.memberDao = memberDao;
	}

	public MemberService() {
		super();
	}

	/**
	 * 로그인 호출후 받은 값이 null이면 Exception Anniversary는 저장후 map으로 넘기는 이유는 jsp로 넘길 때 vo와 list를 함께 보내기 위해서?
	 */
	public HashMap login(MemberVO vo)	throws SQLException,
										InvalidNotFoundException {
		MemberVO mvo = memberDao.login(vo);
		// 만약 mvo가 null 인경우 로그인 불가라는 InvalidNotFoundException을 throw해준다.
		// 이 InvalidNotFoundException을 통해 로그인 실패시 main page를 로그인 페이지로 바꾸기위해 사용함.
		if (mvo == null) {
			throw new InvalidNotFoundException("로그인 불가");
		}
		// 로그인후 기념일을 가져오기 위한 메서드
		// id를 통해 로그인한 회원의 기념을 찾아온다.
		// 기념일은 2개이기에 list를 사용
		List list = memberDao.findAnniversarybyId(vo.getM_id());
		// session에 로그인 정보를 넣기위해 HashMap을 사용.
		HashMap map = new HashMap();
		map.put("mvoLogin",
				mvo);
		map.put("anniLogin",
				list);
		return map;
	}

	/**
	 * 아이디 체크 호출후 받아온값이 있으면 true!
	 */
	public boolean idCheck(String id) throws SQLException {
		// 중복 아이디를 찾는 메서드 그리고 아이디이 존재시 String으로 반환하고, 존재하지 않을경우 null값을 반환한다.
		String m_id = memberDao.idCheck(id);
		// boolean 값으로 중복여부를 체크하기위해 사용
		boolean flag = false;
		// 반환받은 String(id) 값이 존재한다면 flag를 true로 바꾸어준다.
		if (m_id != null) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 이메일 체크 받아온 이메일부분에 '@'가 삽입되어있으면 잘못된 형식. 이라는 Exception 받아온 이메일 앞부분과 @, 뒷부분을 합치고 체크. 받아온 값이 있으면 true!
	 */
	public boolean emailCheck(	String email,
								String portalSite)	throws SQLException,
													InvalidNotFoundException {
		if (email.contains("@")) {
			// 만약 text 입력란에 @가 들어가면 잘못된 입력이므로 Exception 처리
			throw new InvalidNotFoundException("잘못된 형식의 이메일 입니다.");
		}
		// StringBuilder를 사용하여 append메서드를 통해 email과 portalSite를 합쳐 제대로된 이메일의 형식으로 만든다.
		StringBuilder sb = new StringBuilder();
		sb.append(email + "@" + portalSite);
		// 중복 이메일을 찾는 메서드 그리고 이메일이 존재시 String으로 반환하고, 존재하지 않을경우 null값을 반환한다.
		String eamil = memberDao.emailCheck(sb.toString());
		// boolean 값으로 중복여부를 체크하기위해 사용
		boolean flag = false;
		// 반환받은 String(email) 값이 존재한다면 flag를 true로 바꾸어준다.
		if (eamil != null) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 관리자가 수정시 하는 이메일 체크 받아온 이메일부분에 '@'가 삽입되어있으면 잘못된 형식. 이라는 Exception 받아온 이메일 앞부분과 @, 뒷부분을 합치고 체크. 받아온 값이 있으면 true!
	 */
	public HashMap emailCheckByAdmin(	String email,
										String portalSite,
										String userId)	throws SQLException,
														InvalidNotFoundException {
		if (email.contains("@")) {
			throw new InvalidNotFoundException("잘못된 아이디 입니다.");
		}
		System.out.println(userId);
		MemberVO vo = new MemberVO();
		StringBuilder sb = new StringBuilder();
		sb.append(email + "@" + portalSite);
		System.out.println(sb);
		MemberVO mvo = new MemberVO();
		mvo.setM_email(sb.toString());
		mvo.setM_id(userId);
		HashMap map = new HashMap();
		boolean flagByAdmin = false;
		// String inputEmail=email+"@"+portalSite;
		// 관리자가 업데이트시 기존이메일과동일한지 확인하는 메서드
		String emailCheck = memberDao.emailCheckByAdmin(mvo);
		if (emailCheck != null) {
			flagByAdmin = true;
		}
		System.out.println("sss" + emailCheck);
		if (emailCheck == null) {
			System.out.println(sb.toString());
			String eamil = memberDao.emailCheck(sb.toString());
			System.out.println(email + "ddddsss");
			boolean flag = false;
			if (eamil != null) {
				flag = true;
			}
			map.put("flag",
					flag);
		}
		map.put("flagByAdmin",
				flagByAdmin);
		return map;
	}

	/**
	 * 회원의 정보를 가져오는 메서드 강제적으로 웹에서 가입하는 type은 b로(일반회원) member table을 가입시키고 member값이 다 있으면 anniversarytable등록
	 */
	public void registerMember(	MemberVO vo,
								AnniversaryVO avo1,
								AnniversaryVO avo2) throws SQLException {
		// 일반사용자만 가능
		vo.setM_type("b");
		// Member 회원가입
		memberDao.registerMember(vo);

		// Member 기념일 등록
		if (vo != null) {
			memberDao.registerAnniversary(avo1);
			memberDao.registerAnniversary(avo2);
		}
	}

	/**
	 * 회원이 자기정보를 수정할 때 사용한다.
	 */
	public HashMap updateMember(MemberVO vo,
								AnniversaryVO avo1,
								AnniversaryVO avo2)	throws SQLException,
													InvalidNotFoundException {
		vo.setM_type("b");
		memberDao.updateMember(vo);
		memberDao.updateAnniversay(avo1);
		memberDao.updateAnniversay(avo2);
		HashMap map = login(vo);
		return map;
	}

	/**
	 * 회원의 상세정보를 가져온다.
	 */
	public MemberVO memberInfo(String id) throws SQLException {
		return memberDao.memberInfo(id);
	}

	/**
	 * 회원들이 이름과 이메일로 아이디를 찾고자 할때 리턴값이 null이면 Exception
	 */
	public MemberVO findId(MemberVO vo)	throws SQLException,
										InvalidNotFoundException {
		MemberVO mvo = memberDao.findId(vo);
		if (mvo == null) {
			throw new InvalidNotFoundException("찾는 아이디가 없습니다.");
		}
		return mvo;
	}

	/**
	 * 회원들 정보수정시 이메일로 비밀번호를 바꾸고자 할 때
	 */
	public void changePass(MemberVO vo) throws SQLException {
		memberDao.changePass(vo);
	}

	/**
	 * 아이디와 이메일을 통해서 아이디를 받아온다?ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
	 */
	public String findPassword(MemberVO vo) throws SQLException {
		return memberDao.findPassword(vo);
	}

	/**
	 * 관리자 모드시 모든회원들을 조회할 때 //getMemberList(페이징)으로 쓰지 않나?ㅡㅡㅡㅡㅡㅡ
	 */
	public List findAllMemberInfo() throws SQLException {
		int index = 0;
		List list = memberDao.findAllMemberInfo();
		return list;
	}

	/**
	 * 로그인시 해당 회원의 기념일 확인
	 */
	public AnniversaryVO getAnniversary(String id) throws SQLException {
		return (AnniversaryVO) memberDao.findAnniversarybyId(id);
	}

	/**
	 * 관리자가 한 회원의 상세정보를 볼때 Tokenizer를 통해서 이메일의 @를 기준으로 앞부분과 뒷부분을 구분해서 map에 저장후 jsp에서 다른키값으로 뿌린다.
	 */
	public HashMap getMemberInfo(String id) throws SQLException {
		MemberVO mvo = memberDao.memberInfo(id);
		String email = mvo.getM_email();
		StringTokenizer stk = new StringTokenizer(	email,
													"@");
		String a = stk.nextToken();
		String b = stk.nextToken();
		System.out.println("service getMemberInfo a+b " + a + b);
		System.out.println(mvo);
		List list = memberDao.findAnniversarybyId(id);
		System.out.println("service getMemberInfo list " + list);
		HashMap map = new HashMap();
		map.put("memInfo",
				mvo);
		map.put("memEmailF",
				a);
		map.put("memEmailT",
				b);
		map.put("anniInfo",
				list);
		return map;
	}

	/**
	 * 관리자가 사용자 정보수정할때
	 */
	public void updateMemberByAdmin(MemberVO vo,
									AnniversaryVO avo1,
									AnniversaryVO avo2)	throws SQLException,
														InvalidNotFoundException {
		memberDao.updateMemberByAdmin(vo);
		HashMap map = new HashMap();

		memberDao.updateRecipeByAdmin(vo);
		memberDao.updateAnniversayByAdmin(avo1);
		memberDao.updateAnniversayByAdmin(avo2);
	}

	/**
	 * 관리자가 모든회원들을 볼때 페이징으로 보기위해서 사용 처음화면 표현서 페이지번호가 없을때 강제적으로 1을 넣어주고 commonConstans를 통해서 컨텐츠수를 받았다. 페이지 번호와 컨텐츠 갯수를 정의한 인터페이스를 map으로 저장한뒤 넘김 총컨텐츠수와
	 * 페이지넘버를 받아온후 두개를 listVO에 담아 jsp로 넘긴다.
	 */
	public ListVO getMemberList(String pageNo) throws SQLException {
		if (pageNo == null || pageNo == "")
			pageNo = "1";
		int numberPerPage = CommonConstants.CONTENT_NUMBER_PER_PAGE;
		HashMap map = new HashMap();
		map.put("pageNo",
				pageNo);
		map.put("numberPerPage",
				numberPerPage);
		List<MemberVO> list = memberDao.getMemberList(map);
		int total = memberDao.totalContent();
		PagingBean paging = new PagingBean(	total,
											Integer.parseInt(pageNo));
		ListVO lvo = new ListVO(list,
								paging);
		return lvo;
	}

	/**
	 * 회원아이디를 통해서 member와 anniversary table삭제. //deleteRecipeDesc,deleteRecipeType,deleteRecipe
	 */
	/**
	 * delete from recipe_desc where r_no='23' delete from recipe where r_no='23' delete from anniversary where m_id='123' delete from member where
	 * m_id='123'
	 */
	public void deleteMember(String mid) throws SQLException {
		System.out.println("service deleteMember mid:" + mid);
		memberDao.deleteFavorite(mid);// 즐겨찾기 삭제
		memberDao.deleteRecipeReply(mid);// 리플삭제
		memberDao.deleteRecipeGrade(mid);// 등급삭제
		List recipeList = memberDao.selectAllRecipe(mid); // 삭제전 회원의 작성된 글을 모두 받아온다.
		System.out.println("service recipeList:" + recipeList);
		System.out.println("sdfsdfsfdd" + recipeList);
		memberDao.deleteFavorite(mid);// 즐켜찾기 삭제
		memberDao.deleteRecipeReply(mid);// 리플삭제
		memberDao.deleteRecipeGrade(mid);// 등급삭제
		for (int i = 0; i < recipeList.size(); i++) {
			memberDao.deleteRecipeDesc((Integer) recipeList.get(i));
			memberDao.deleteRecipe((Integer) recipeList.get(i));
			// 랭킹 목록 삭제
			memberDao.rankingDelete((Integer) recipeList.get(i));
		}
		memberDao.deleteQna_Board_replyByMemberId(mid);// QNA 게시판 리플 삭제
		memberDao.deleteQnaBoardByMemberId(mid);// QNA 게시판삭제
		memberDao.deleteAnniByMemberId(mid); // 회원 탈퇴시 기념일 삭제
		memberDao.deleteNoticeContent(mid); // 회원 탈퇴시 공지사항 삭제
		memberDao.deleteFree_Board_replyByMemberId(mid);// 자유게시판 게시판 리플 삭제
		memberDao.deleteFreeContent(mid); // 회원 탈퇴시 자유게시판 삭제
		memberDao.deleteMember(mid); // 회원삭제
	}

	public MemberVO changePassword(HashMap map)	throws SQLException,
												InvalidNotFoundException {
		MemberVO vo = (MemberVO) map.get("vo"); //
		String pass = (String) map.get("pass"); // 기좀패스(검사할꺼)
		String id = (String) map.get("id");
		vo.setM_password(pass);// 기존패스 할당
		vo.setM_id(id);// 기존 아이디 검사
		System.out.println("service changePassword id,pass,vo:" + id + pass + vo);
		String mid = memberDao.checkPasswordById(vo);
		if (mid == null) {
			throw new InvalidNotFoundException("잘못된 입력");
		}
		System.out.println("service changePassword mid:" + mid);
		String pass1 = (String) map.get("pass1");
		vo.setM_password(pass1);
		System.out.println("service chagnePassword vo" + vo);
		memberDao.changePasswordById(vo);
		return memberDao.memberInfo(mid);
	}

	/**
	 * 관리자가 회원리스트를 검색조건을 통해 검색하는 메서드
	 */
	public Admin_ListVO searchByMemberInfo(HashMap map) throws SQLException {
		String pageNo = (String) map.get("pageNo");// map에 들어있는 Page 번호
		MemberVO vo = (MemberVO) map.get("mvo");// map에 id, email, name은 MemberVO에 담겨져 있다.
		if (pageNo == null || pageNo == "")
			pageNo = "1";// page 번호가 null이거나 없으면 1로 세팅
		int numberPerPage = CommonConstants.CONTENT_NUMBER_PER_PAGE;// 페이징 정책적용 : 한 페이지에 보여줄 게시물 수
		// PageNo와 email, name, id와 한 페이지에 보여줄 게시물 수 를 map에 넣는다.
		map.put("pageNo",
				pageNo);
		map.put("numberPerPage",
				numberPerPage);
		map.put("m_id",
				vo.getM_id());
		map.put("m_email",
				vo.getM_email());
		map.put("m_name",
				vo.getM_name());
		// 위에서 언급한 map을 인자값으로 검색조건에 알맞은 List로 뽑아내는 메서드
		List list = memberDao.searchByMemberInfo(map);
		// 검색 조건에 맞는 총게시물수를 뽑기위해 사용하는 메서드
		int total = -1;
		if (vo.getM_email() != null && vo.getM_id() != null) {

		}
		else {

			total = memberDao.totalContentByAdmin(vo);
		}
		// 페이징 적용
		PagingBean paging = new PagingBean(	total,
											Integer.parseInt(pageNo));
		// 관리자가 검색시 사용하는 ListVO
		Admin_ListVO lvo = new Admin_ListVO(list,
											paging,
											map);
		return lvo;
	}

}
